/**
 * @author xiaobyu
 * @created Mar 25, 2016
 * 
 */
package nconv.convert;

import nconv.convert.WikiMarks.WikiFormatMark;
import nconv.utils.LogCenter;
import org.apache.poi.hwpf.HWPFDocumentCore;
import org.apache.poi.hwpf.model.StyleDescription;
import org.apache.poi.hwpf.model.StyleSheet;
import org.apache.poi.hwpf.usermodel.*;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static nconv.convert.WikiFormatUtils.*;

public class WikiConverter extends BaseWordConverter{
	
	static POILogger logger = POILogFactory.getLogger(WikiConverter.class);
	public static final String DOC_NAME = "DocName";
	public static final String PAGE_NAME = "PageName";

	public static final String ATTR_STYLE_NAME = "StyleName";
	public static final String BULLET_LABEL = "BulletLabel";
	public static final String HEADING_CLAUSE = "HeadingClause";
	public static final String MARK_PAGE_CLAUSE = "MarkPageClause";
	public static final String BOOKMARK_NAME = "BookMarkName";
	public static final String HYPER_LINK = "HyperLink";
	public static final String PAGE_REF = "PageRef";
	public static final String IMAGE_NAME = "ImageName";
	public static final String IMAGE_NAME_SEPARATOR = "<\3\4>";
	public static final String FOT_CAPTION_MARK = "FigureOrTableCaptionMark";
	public static final String FOT_NAME = "FigureOrTableName";


	public static final String FOT_CAPTION_STATE_YES = "true";
	public static final String FOT_CAPTION_STATE_TBD = "suspicious";


	public static final String FLATTEN_MARK = "FlattenMark";

	public static final String WIKI_STYLE_HEADING = "WikiStyleHead";
	public static final String WIKI_STYLE_LIST = "WikiStyleList";
	public static final String WIKI_TABLE_MARK = "WikiTableMark";

	private static final int DEFAULT_IMAGE_WIDTH = 600;
	private static final int MAX_IMAGE_WIDTH = 842;

	private final static Pattern notePatten = Pattern.compile("([Nn][Oo][Tt][Ee]\\s*(\\d+)?:).*");
	private final static Pattern enumValuePattern = Pattern.compile("[^\\w\\-]([0-9A-Z]\\w+(_[0-9A-Z]\\w+)+)[^\\w\\-]");
	/**
	 * Need the doc name for clause referencing
	 */
	protected String docName;
	protected List<String> imageNames;

	int autoPicIdx = 0;
	protected String heading = null;
	
	public WikiConverter(String docName) {
		textDocumentFacade.getHead().setAttribute(DOC_NAME, docName);
		this.docName = docName;
		setPicturesManager(new WikiPicturesManager(docName));
		imageNames = new ArrayList<>();
	}

	public void summary() {

	}
	
	protected boolean shallFormat(Paragraph p, String styleName) {
		if (styleName != null && styleName.startsWith("TOC")) {
			return false;
		} 
		return true;
	}
	
	protected void processBookmarks(HWPFDocumentCore wordDocument,
	    Element currentBlock, Range range, int currentTableLevel,
	    List<Bookmark> rangeBookmarks) {
		Element parent = currentBlock;
		for (Bookmark bm : rangeBookmarks) {
			Element e = textDocumentFacade.createBlock();
			e.setAttribute(BOOKMARK_NAME, bm.getName());
			parent.appendChild(e);
			parent = e;
		}
		
		if (range != null) {
			processCharacters(wordDocument, currentTableLevel, range, parent);
		}
	}

	protected void processPageref(HWPFDocumentCore hwpfDocument, Element currentBlock, Range textRange,
	    int currentTableLevel, String pageref) {
		Element basicLink = textDocumentFacade.createBlock();
		currentBlock.appendChild(basicLink);
		basicLink.setAttribute(PAGE_REF, pageref);

		if (textRange != null)
			processCharacters(hwpfDocument, currentTableLevel, textRange, basicLink);
	}
	
	protected void processHyperlink(HWPFDocumentCore wordDocument, Element currentBlock, 
			Range textRange,  int currentTableLevel, String hyperlink) {
		Element basicLink = textDocumentFacade.createBlock();
		basicLink.setAttribute(HYPER_LINK, hyperlink);
		currentBlock.appendChild(basicLink);

		if (textRange != null)
			processCharacters(wordDocument, currentTableLevel, textRange, basicLink);
	}

	@Override
  protected void processParagraph(HWPFDocumentCore wordDocument,
      Element parentElement, int currentTableLevel, Paragraph paragraph,
      String bulletText) {
    
    StyleSheet styleSheet = wordDocument.getStyleSheet();
    StyleDescription paragraphStyle = styleSheet.getStyleDescription(paragraph.getStyleIndex());
		String styleName = paragraphStyle.getName();
		if (!shallFormat(paragraph, styleName))  return;

		Element pElement = textDocumentFacade.createParagraph();
		parentElement.appendChild( pElement );

		pElement.setAttribute(ATTR_STYLE_NAME, styleName);
		setFormatAttrs(pElement, paragraph, bulletText);
		preProcessParagraph(parentElement, pElement, paragraph);
    processCharacters( wordDocument, currentTableLevel, paragraph, pElement );
    postProcessParagraph(parentElement, pElement, paragraph);
    compactParagraph(parentElement, pElement, paragraph);
  }
	protected void processImage(Element currentBlock, boolean inlined, Picture picture, String url) {
		int index = url.indexOf(':');
		int width = 0;
		if (index > 0) {
			try {
				width = Integer.parseInt(url.substring(index + 1));
				url = url.substring(0, index);
			} catch (Exception e) {}
		}
		imageNames.add(url);
		Element p = textDocumentFacade.createBlock();
		currentBlock.appendChild(p);
		p.setAttribute(IMAGE_NAME, url);
		if (width <= 0) {
			width = DEFAULT_IMAGE_WIDTH;
		} else if (width > MAX_IMAGE_WIDTH) {
			width = MAX_IMAGE_WIDTH;
		}
		p.appendChild(textDocumentFacade.createText(
				"[[File:" + url  + "|" + width + "px|center"
					//	+ "|" + FOT_HOLDER_START + url + FOT_HOLDER_END + "]]"));
					+ "]]"));
	}
	
	protected void setFormatAttrs(Element element, Paragraph paragraph, String bulletText) {
		if (ConvertUtils.isHeading(element)) {
			String styleName = getStyleName(element);
			int headingLevel = -1;
			try {
				headingLevel = Integer.parseInt(styleName.substring(8));
			} catch (Exception e) {
				String[] candidates = styleName.substring(8).split(",");
				for (String candidate : candidates) {
					try {
						headingLevel = Integer.parseInt(candidate);
						break;
					} catch (Exception ee) {}
				}
			}
			if (headingLevel > 0) {
				element.setAttribute(WIKI_STYLE_HEADING, ConvertUtils.getSameCharStr('=', headingLevel));
			}
		}

		if (paragraph.isInList() && bulletText.length() > 0) {
			bulletText = bulletText.trim();
			if (bulletText.length() == 1 && bulletText.charAt(0) > 0x8F) {
				element.setAttribute(WIKI_STYLE_LIST, "*");
			} else if (bulletText.length() > 0) {
				element.setAttribute(WIKI_STYLE_LIST, ":");
				element.setAttribute(BULLET_LABEL, bulletText);
			} else {
				element.setAttribute(WIKI_STYLE_LIST, "*");
			}
		}
	}


	protected void compactParagraph(Element parentElement, Element element, Paragraph p) {

		List<String> imageNames = new ArrayList<>();
		ConvertUtils.scanImageNames(element, imageNames);

		WikiMarks marks = mergeWikiFormatMarks(element);

		String text = getFlattenElementText(element);

		//remove left spaces, the marks need to be updated as well
		if (!shouldKeepSpaces(text)) {
			int leftSpaceCount = 0;
			int maximumRemovable = marks.getLeftMaximumRemovableCharacters();
			for (int i = 0; i < text.length() && i <= maximumRemovable; i++) {
				char ch = text.charAt(i);
				if (ch == ' ' || ch == '\t') leftSpaceCount++;
				else break;
			}
			if (leftSpaceCount > 0) {
				text = text.substring(leftSpaceCount);
				if (marks != null) {
					for (WikiFormatMark mark : marks.getWikiMarkList()) {
						mark.start -= leftSpaceCount;
						if (mark.start < 0) {
							mark.start = 0;
						}
						mark.end -= leftSpaceCount;
					}
				}
			}
		}

		String lcTrimed = text.trim().toLowerCase();
		if (lcTrimed.length() > 0 && (lcTrimed.startsWith("figure") || lcTrimed.startsWith("table")) &&
				",.;".indexOf(lcTrimed.charAt(lcTrimed.length() - 1)) < 0) {
			element.setAttribute(FOT_CAPTION_MARK, FOT_CAPTION_STATE_TBD);
		}

		if (ConvertUtils.isHeading(element)) {
			heading = text.trim();
		}

		text = formatWikiParagraph(text, marks, element);

		emptyNode(element);
		if (text.length() == 0) {
			element.appendChild(textDocumentFacade.createText(p.isInTable() ? LINE_BREAK : EMPTY_STRING));
		} else {
			if (!ConvertUtils.isHeading(element)) {
				text += LINE_BREAK;
			}
			element.appendChild(textDocumentFacade.createText(text + LINE_BREAK));
		}

		if (imageNames.size() > 0) {
			StringBuilder sb = new StringBuilder();
			for (String name : imageNames) {
				sb.append((sb.length() > 0 ? IMAGE_NAME_SEPARATOR : "") + name);
				break; //TODO need to handle multi-image case
			}
			element.setAttribute(IMAGE_NAME, sb.toString());
		}

	}

	protected boolean shouldKeepSpaces(String text) {
		return false;
	}

	protected String formatWikiParagraph(String text, WikiMarks marks, Element element) {
		if (marks == null || marks.size() == 0) return text;

		TreeMap<Integer, StringBuilder> map = new TreeMap<>();
		boolean isHeading = ConvertUtils.isHeading(element);
		for (WikiFormatMark mark : marks.sort()) {
			StringBuilder start = map.get(mark.start);
			if (start == null) {
				start = new StringBuilder();
				map.put(mark.start, start);
			}
			StringBuilder end = map.get(mark.end);
			if (end == null) {
				end = new StringBuilder();
				map.put(mark.end, end);
			}

			if ((mark.type != fmtListLabel && mark.type != fmtListSymbol) || !isHeading)
				mark.type.handle(start, end, mark.content);
		}
		int adjustedOffset = 0;
		for (int idx : map.keySet()) {
			String str = map.get(idx).toString();
			if (str.length() == 0) continue;

			text = text.substring(0, idx + adjustedOffset) + str + text.substring(idx + adjustedOffset);
			adjustedOffset += str.length();

		}
		return text;
	}
	
	protected void removeTextBefore(Element element, int idx) {
		if (idx <= 0) return;
		LinkedList<Node> ll = new LinkedList<>(ConvertUtils.getChildNodeList(element));
		int vidx = 0;
		Node located = null;
		while (ll.size() > 0) {
			Node node = ll.pollFirst();
			if (node instanceof Text) {
				String text = ((Text)node).getData();
				if (idx > vidx + text.length()) {
					vidx += text.length();
					continue;
				}	else if (idx == vidx + text.length()){
					located = node;
					break;
				} else {
					((Text)node).setData(text.substring(idx - vidx));
					Node dummy = textDocumentFacade.createText("");
					node.getParentNode().insertBefore(dummy, node);
					located = dummy;
					break;
				}
			} else {
				ll.addAll(0, ConvertUtils.getChildNodeList(node));
			}
		}

		ConvertUtils.removeLeftNodes(located, element, true);
	}

	//protected Map<Element, List<WikiFormatMark>> elementWikiMarkMap = new HashMap<>();

	protected final WikiMarks mergeWikiFormatMarks(Element element) {
		WikiMarks marks = getNativeWikiFormatMarks(element);
		mergeUserWikiFormatMarks(marks, element);
		return marks;
	}

	/**
	 * Traverse all the child nodes and gather the wiki format marks, the text will
	 * also be catenated as a single Text node inserted to the element.
	 *
	 * @param element The element to be processed
	 * @return List of WikiFormatMark
	 */
	protected WikiMarks getNativeWikiFormatMarks(Element element) {
		WikiMarks marks = new WikiMarks();
		if (element.hasAttribute(WIKI_STYLE_HEADING)) {
			marks.addMark(new WikiFormatMark(fmtHeading, element.getAttribute(WIKI_STYLE_HEADING)));
		}
		if (element.hasAttribute(WIKI_STYLE_LIST)) {
			marks.addMark(new WikiFormatMark(fmtListSymbol, element.getAttribute(WIKI_STYLE_LIST), 0, 0));
			if (element.hasAttribute(BULLET_LABEL) && element.getAttribute(BULLET_LABEL).length() > 0) {
				marks.addMark(new WikiFormatMark(fmtListLabel, element.getAttribute(BULLET_LABEL), 0, 0));
			}
		}

		StringBuilder sb = new StringBuilder();

		if (element.hasAttribute(BOOKMARK_NAME)){
			marks.addMark(new WikiFormatMark(fmtBookmark, element.getAttribute(BOOKMARK_NAME)));
		}

		if (element.hasAttribute(HYPER_LINK)) {
			marks.addMark(new WikiFormatMark(fmtHyperLink, element.getAttribute(HYPER_LINK)));
		}

		if (element.hasAttribute(PAGE_REF)) {
			marks.addMark(new WikiFormatMark(fmtInternalLink, element.getAttribute(PAGE_REF)));
		}

		StringBuilder tsb = new StringBuilder();
		if (element.hasChildNodes()) {
			for (Node child : ConvertUtils.getChildNodeList(element)) {
				if (child instanceof Text) {
					tsb.append(((Text)child).getData());
				} else {
					Element childElement = (Element)child;
					WikiMarks childMarks = getNativeWikiFormatMarks(childElement);
					for (WikiFormatMark mark : childMarks.getWikiMarkList()) {
						int length = mark.end - mark.start;
						mark.start += tsb.length();
						mark.end = mark.start + length;
						marks.addMark(mark);
					}
					if (childElement.hasAttribute(IMAGE_NAME)) {
						if (element.hasAttribute(IMAGE_NAME)) {
							System.err.println("FOT_NAME attr was already set while merging child attributes: " + element.getAttribute(FOT_NAME));
						}
						element.setAttribute(IMAGE_NAME, childElement.getAttribute(IMAGE_NAME));
					}
					tsb.append(getFlattenElementText(childElement));
				}
				element.removeChild(child);
			}
		}

		for (WikiFormatMark mark : marks.getWikiMarkList()) {
			if (mark.start == Integer.MIN_VALUE)
				mark.start = 0;

			if (mark.end == Integer.MAX_VALUE)
				mark.end = tsb.length();
		}
		element.setAttribute(FLATTEN_MARK, "true");
		element.appendChild(textDocumentFacade.createText(tsb.toString()));

		return marks;
	}

	protected String getFlattenElementText(Element element) {
		if (element.hasAttribute(FLATTEN_MARK)) {
			return ((Text)element.getChildNodes().item(0)).getData();
		} else {
			System.err.println("Trying to get text from a non-flatten element");
			return null;
		}
	}

	protected void mergeUserWikiFormatMarks(WikiMarks marks, Element element) {
		String text = getFlattenElementText(element);
		int length = text.length();
		if (length >= 6) {
			Matcher m = notePatten.matcher(text);
			if (m.find()) {
				marks.addMark(new WikiFormatMark(fmtBold, null, m.start(1), m.end(1)));
			}
		}

		if (length >= 7) {
			Matcher m = enumValuePattern.matcher(text);
			int lastEnd = 0;
			while (m.find(lastEnd)) {
				marks.addMark(new WikiFormatMark(fmtTemplate, "EnumValue", m.start(1), m.end(1)));
				lastEnd = m.end(1);
			}
		}
	}
	
	protected String getElementText(Node element) {
		if (element instanceof Text) {
			return ((Text)element).getData();
		} else {
			if (((Element)element).hasAttribute(FLATTEN_MARK)) {
				return getFlattenElementText((Element)element);
			}

			StringBuffer sb = new StringBuffer();
			if (element.hasChildNodes()) {
				NodeList nl = element.getChildNodes();
				for (int i = 0; i < nl.getLength(); i++) {
					sb.append(getElementText(nl.item(i)));
				}
			} 
			return sb.toString();
		}
	}
	
	protected void preProcessParagraph(Element parentElement, Element thisElement, Paragraph p) {
		if (ConvertUtils.isHeading(thisElement)) {
			LogCenter.log("Processing heading: " + p.text());
		}
	}
	
	protected void postProcessParagraph(Element parentElement, Element thisElement, Paragraph p) {
	}
	
	protected void emptyNode(Node inNode) {
		if (!inNode.hasChildNodes()) return;
		
		NodeList nl = inNode.getChildNodes();
		Node[] nodes = new Node[nl.getLength()];
		for (int i = 0; i < nodes.length; i++) {
			nodes[i] = nl.item(i);
		}
		
		for (Node node : nodes) {
			inNode.removeChild(node);
		}
	}

	protected void attachFOT(Element fotElement, Element titleElement) {
		fotElement.setAttribute(FOT_NAME, getFlattenElementText(titleElement));
		titleElement.setAttribute(FOT_CAPTION_MARK, FOT_CAPTION_STATE_YES);

		LinkedList<Node> nodes = new LinkedList<>(ConvertUtils.getChildNodeList(titleElement));
		while (nodes.size() > 0) {
			Node node = nodes.pollFirst();
			if (node instanceof Text) {
				String content = ((Text)node).getData();
				String lowerContent = content.toLowerCase();
				if (lowerContent.contains("figure") || lowerContent.contains("table")) {
					int lbIndex = content.indexOf('\n');
					content = "'''<span style=\"width:100%;text-align:center;display:block;\">"
							+ (lbIndex > 0 ? content.substring(0, lbIndex) : content) + "</span>'''"
							+ (lbIndex > 0 ? content.substring(lbIndex) : "");
					((Text)node).setData(content);
					break;
				}
			} else if (node.getChildNodes().getLength() > 0) {
				nodes.addAll(ConvertUtils.getChildNodeList(node));
			}
		}
	}

	public void processDocument(HWPFDocumentCore wordDocument) {
		super.processDocument(wordDocument);

		//processFOT();

		List<Element> list = scanTableAndFigureInfo();// new ArrayList<>();
		int infoIndex = 0;

		if (list.size() >= 2) { //at least two elements are required for a mapping
			LinkedList<Node> ll = new LinkedList<>(ConvertUtils.getChildNodeList(getDocumentBody()));
			Element lastTitleNode = null;
			Element lastFigureOrTable = null;
			while (ll.size() > 0) {
				Node node = ll.pollFirst();

				if (node instanceof Text) {
					System.err.println("Unexpected text node: " + ((Text)node).getData());
				} else {
					Element element = (Element) node;
					if (node == list.get(infoIndex)) {
						boolean canAttach = false;
						if (element.hasAttribute(WikiConverter.WIKI_TABLE_MARK)) {
							if (lastTitleNode != null) {
								canAttach = true;
							}
							lastFigureOrTable = element;
						} else if (element.hasAttribute(WikiConverter.IMAGE_NAME)) {
							if (lastTitleNode != null) {
								canAttach = true;
							}
							lastFigureOrTable = element;
						} else { //possible figure title or page title
							lastTitleNode = element;
							if (lastFigureOrTable != null) {
								canAttach = true;
							}
						}
						if (canAttach) {
							attachFOT(lastFigureOrTable, lastTitleNode);

							lastTitleNode = null;
							lastFigureOrTable = null;
						}
						if (infoIndex == list.size() - 1) break;
						infoIndex++;

					} else {
						if (element.hasAttribute(FLATTEN_MARK)) {
							String content = getFlattenElementText(element);
							if (content.trim().length() > 0) {
								lastTitleNode = null;
								lastFigureOrTable = null;
							}
						} else {
							ll.addAll(0, ConvertUtils.getChildNodeList(element));
						}
					}
				}
			}
		}
	}

	private List<Element> scanTableAndFigureInfo() {
		List<Element> resultList = new ArrayList<>();
		LinkedList<Node> ll = new LinkedList<>(ConvertUtils.getChildNodeList(textDocumentFacade.getBody()));

		while (ll.size() > 0) {
			Node node = ll.pollFirst();
			if (node instanceof Text) continue;

			Element element = (Element)node;
			if (ConvertUtils.isHeading(element)) {
				continue;
			}
			if (element.hasAttribute(FLATTEN_MARK)) {
				if (element.hasAttribute(WikiConverter.IMAGE_NAME)) {
					resultList.add(element);
				} else if (element.hasAttribute(WikiConverter.FOT_CAPTION_MARK)) {
					resultList.add(element);
				}
			} else {
				if (element.hasAttribute(WikiConverter.WIKI_TABLE_MARK)) {
					resultList.add(element);
				} else {
					ll.addAll(0, ConvertUtils.getChildNodeList(element));
				}
			}
		}
		return 	resultList;

	}

	@Override
	protected void processTable(HWPFDocumentCore wordDocument, Element flow, Table table) {
		Element tableHeader = textDocumentFacade.createTableRow();
		Element tableBody = textDocumentFacade.createTableBody();

		final Element tableElement = textDocumentFacade.createTable();
		tableElement.setAttribute(WIKI_TABLE_MARK, "true");
		tableElement.appendChild(textDocumentFacade.createText(
				"{|class=\"wikitable collapsible\"\n"
		//		+ "|+" + FOT_HOLDER_START + tableName + FOT_HOLDER_END + "\n"));
		));

		final int[] tableCellEdges = ConvertUtils.buildTableCellEdgesArray(table);
		final int tableRows = table.numRows();

		int maxColumns = Integer.MIN_VALUE;
		for (int r = 0; r < tableRows; r++) {
			maxColumns = Math.max(maxColumns, table.getRow(r).numCells());
		}

		for (int r = 0; r < tableRows; r++) {
			TableRow tableRow = table.getRow(r);
			Element tableRowElement = textDocumentFacade.createTableRow();

			// index of current element in tableCellEdges[]
			int currentEdgeIndex = 0;
			final int rowCells = tableRow.numCells();
			for (int c = 0; c < rowCells; c++) {
				TableCell tableCell = tableRow.getCell(c);

				if (tableCell.isVerticallyMerged() && !tableCell.isFirstVerticallyMerged()) {
					currentEdgeIndex += getNumberColumnsSpanned(tableCellEdges, currentEdgeIndex, tableCell);
					continue;
				}


				int colSpan = getNumberColumnsSpanned(tableCellEdges, currentEdgeIndex, tableCell);
				currentEdgeIndex += colSpan;

				if (colSpan == 0)
					continue;

				final int rowSpan = getNumberRowsSpanned(table, tableCellEdges, r, c, tableCell);

				String content = (r == 0 && tableRows > 1) ? "!" : "|";
				if (colSpan != 1 || rowSpan != 1) {
					if (colSpan != 1) {
						content += " colspan=\"" + colSpan + "\"";
					}
					if (rowSpan != 1) {
						content += " rowspan=\"" + rowSpan + "\"";
					}
					content += "|";
				}
				tableRowElement.appendChild(textDocumentFacade.createText(content));
				Element tableCellElement = textDocumentFacade.createTableCell();
				processParagraphes(wordDocument, tableCellElement, tableCell, table.getTableLevel());
				//TODO remove last spaces
				String cellContent = getElementText(tableCellElement);
				if (cellContent.startsWith("-")) {
					tableRowElement.appendChild(textDocumentFacade.createText("\n"));
				}
				tableRowElement.appendChild(tableCellElement);
			}

			if (tableRow.isTableHeader()) {
				tableHeader.appendChild(tableRowElement);
			} else {
				tableBody.appendChild(tableRowElement);
			}
			
			if (r == tableRows - 1) { //last row
				tableRowElement.appendChild(textDocumentFacade.createText("|}\n"));
			} else {
				tableRowElement.appendChild(textDocumentFacade.createText("|-\n"));
			}
		}

		if (tableHeader.hasChildNodes()) {
			tableElement.appendChild(tableHeader);
		}
		if (tableBody.hasChildNodes()) {
			tableElement.appendChild(tableBody);
			flow.appendChild(tableElement);
		} else {
			logger.log(POILogger.WARN, "Table without body starting at [", table.getStartOffset(), "; ",
			    table.getEndOffset(), ")");
		}
	}
	
	protected String getStyleName(Element element) {
		return element.getAttribute(ATTR_STYLE_NAME);
	}
}
